package com.hexiang.web;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hexiang.response.CommonResponse;
import com.hexiang.service.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.Callable;

@RestController
@Slf4j
public class AsyncCallableController {
    private final TaskService taskService;

    @Resource
    private ObjectMapper objectMapper;

    @Autowired
    public AsyncCallableController(TaskService taskService) {
        this.taskService = taskService;
    }

    @GetMapping(value = "/callable", produces = "application/json")
    public Callable<CommonResponse> callable() {
        log.info("callableStart");
        Callable<CommonResponse> callable = taskService::execute;
        log.info("callableEnd");
        return callable;
    }

    @PostMapping(value = "/callablePost", produces = "application/json")
    public Callable<CommonResponse> callablePost(@RequestBody String jsonString) throws JsonProcessingException {
        log.info("callablePostStart");
        String name = (String) objectMapper.readValue(jsonString, Map.class).get("name");
        Callable<CommonResponse> callable = () -> taskService.execute(name);
        log.info("callablePostEnd");
        return callable;
    }

    @GetMapping(value = "/callableTimeOut", produces = "application/json")
    public Callable<CommonResponse> callableTimeOut() {
        log.info("callableTimeOutStart");
        Callable<CommonResponse> callable = taskService::timeout;
        log.info("callableTimeOutEnd");
        return callable;
    }

    @GetMapping(value = "/callableErr", produces = "application/json")
    public Callable<CommonResponse> callableErr() {
        log.info("callableErrStart");
        Callable<CommonResponse> callable = taskService::executeErr;
        log.info("callableErrEnd");
        return callable;
    }
}